﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Modbus;
using Modbus.Data;
using Modbus.Device;

namespace ModMaster
{
    public partial class frmSend : Form
    {
        IModbusSerialMaster mb_master;
        byte mb_slave_id;
        mb_data mbd;
        int mbd_type;
        string mbd_value;

        public frmSend(IModbusSerialMaster master, byte slave_id, mb_data data, int type, string value)
        {
            InitializeComponent();

            mb_master = master;
            mb_slave_id = slave_id;
            mbd = data;
            mbd_type = type;
            mbd_value = value;

            this.Text = "写入数据 - " + data.name;
            if (mbd_type == 0)
            {
                cbo_type.Items.Add("WriteSingleCoil");
                cbo_type.Items.Add("WriteMultipleCoils");
            }
            else
            {
                cbo_type.Items.Add("WriteSingleRegister");
                cbo_type.Items.Add("WriteMultipleRegisters");
            }
            cbo_type.SelectedIndex = 1;
            num_address.Value = mbd.address;
            if ((mbd.values != null) && (mbd.values.Length > 0))
            {
                txt_value.Visible = false;
                num_value.Visible = false;

                for (int i = 0; i < mbd.values.Length; i++)
                {
                    cbo_value.Items.Add(mbd.values[i].value);
                }
                cbo_value.SelectedIndex = 0;
                cbo_value.Text = mbd_value;
            }
            else if (type <= 1)
            {
                txt_value.Visible = false;
                num_value.Visible = false;

                cbo_value.Items.Add("false");
                cbo_value.Items.Add("true");
                cbo_value.SelectedIndex = 0;
                cbo_value.Text = mbd_value;
            }
            else
            {
                string value_type = mbd.value_type.ToLower();

                if ((value_type == "bits") || (value_type == "hex"))
                {
                    num_value.Visible = false;
                    cbo_value.Visible = false;

                    txt_value.Text = value;
                    txt_value.SelectAll();
                }
                else
                {
                    txt_value.Visible = false;
                    cbo_value.Visible = false;

                    if ((mbd.format != null) && (mbd.format.ToLower().StartsWith("f")))
                    {
                        int dp;
                        if (int.TryParse(mbd.format.Substring(1), out dp))
                        {
                            num_value.DecimalPlaces = dp;
                        }
                    }
                    {
                        double v_tmp = 0;
                        double.TryParse(value, out v_tmp);
                        num_value.Value = (decimal)v_tmp;
                    }
                    num_value.Select(0, 32);
                }
            }
        }

        private void Btn_cancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        private void Btn_send_Click(object sender, EventArgs e)
        {
            try
            {
                txt_result.Text = "发送中...";
                if (mbd_type == 0)
                {
                    if (cbo_type.SelectedIndex == 0)
                    {
                        mb_master.WriteSingleCoil(mb_slave_id, (UInt16)mbd.address, cbo_value.SelectedIndex == 1);
                    }
                    else
                    {
                        bool[] bools = new bool[1];
                        bools[0] = cbo_value.SelectedIndex == 1;
                        mb_master.WriteMultipleCoils(mb_slave_id, (UInt16)mbd.address, bools);
                    }
                }
                else if (mbd_type == 2)
                {
                    string value_type = mbd.value_type.ToLower();
                    int length = mbd.length;
                    byte order = frmMain.order_parse(mbd.order.ToUpper());
                    List<ushort> registers = new List<ushort>();

                    if (value_type == "bits")
                    {
                        string value = "0";
                        if (cbo_value.Visible)
                        {
                            value = mbd.values[cbo_value.SelectedIndex].key;
                        }
                        else
                        {
                            value = txt_value.Text;
                        }
                        registers.AddRange(frmMain.bytes_to_registers(frmMain.string_to_bits(value), order));
                    }
                    else if (value_type == "hex")
                    {
                        string value = "0";
                        if (cbo_value.Visible)
                        {
                            value = mbd.values[cbo_value.SelectedIndex].key;
                        }
                        else
                        {
                            value = txt_value.Text;
                        }
                        registers.AddRange(frmMain.bytes_to_registers(frmMain.string_to_bytes(value), order));
                    }
                    else
                    {
                        double value = 0;
                        if (cbo_value.Visible)
                        {
                            value = double.Parse(mbd.values[cbo_value.SelectedIndex].key);
                        }
                        else
                        {
                            value = (double)num_value.Value;
                        }

                        double scale = mbd.scale;
                        if (scale == 0)
                        {
                            scale = 1;
                        }
                        if (length < 1)
                        {
                            length = 1;
                        }
                        if (value_type == "uint16_t")
                        {
                            registers.AddRange(frmMain.bytes_to_registers(BitConverter.GetBytes((UInt16)(value / scale + 0.5)), order));
                        }
                        else if (value_type == "uint32_t")
                        {
                            registers.AddRange(frmMain.bytes_to_registers(BitConverter.GetBytes((UInt32)(value / scale + 0.5)), order));
                        }
                        else if (value_type == "uint64_t")
                        {
                            registers.AddRange(frmMain.bytes_to_registers(BitConverter.GetBytes((UInt64)(value / scale + 0.5)), order));
                        }
                        else if (value_type == "int16_t")
                        {
                            registers.AddRange(frmMain.bytes_to_registers(BitConverter.GetBytes((Int16)(value / scale + 0.5)), order));
                        }
                        else if (value_type == "int32_t")
                        {
                            registers.AddRange(frmMain.bytes_to_registers(BitConverter.GetBytes((Int32)(value / scale + 0.5)), order));
                        }
                        else if (value_type == "int64_t")
                        {
                            registers.AddRange(frmMain.bytes_to_registers(BitConverter.GetBytes((Int64)(value / scale + 0.5)), order));
                        }
                        else if (value_type == "float")
                        {
                            registers.AddRange(frmMain.bytes_to_registers(BitConverter.GetBytes((Single)(value / scale)), order));
                        }
                        else if (value_type == "double")
                        {
                            registers.AddRange(frmMain.bytes_to_registers(BitConverter.GetBytes((Double)(value / scale)), order));
                        }
                    }

                    if (cbo_type.SelectedIndex == 0)
                    {
                        for (int i = 0; i < registers.Count; i++)
                        {
                            mb_master.WriteSingleRegister(mb_slave_id, (UInt16)(mbd.address + i), registers[i]);
                        }
                    }
                    else
                    {
                        mb_master.WriteMultipleRegisters(mb_slave_id, (UInt16)mbd.address, registers.ToArray());
                    }
                }
                txt_result.Text = "发送完成";
                if (chk_result.Checked)
                {
                    this.DialogResult = DialogResult.OK;
                }
            }
            catch (SlaveException ex)
            {
                txt_result.Text = "应答异常码: " + ex.SlaveExceptionCode.ToString();
            }
            catch (Exception ex)
            {
                txt_result.Text = ex.Message;
            }
        }
    }
}
